<?php

namespace app\controller\Api\V1\Client;

use app\helper\GetProductInfo;
use app\model\AutoTaskRecord;
use app\model\GameGiftBag;
use app\model\GameGiftBagRecord;
use app\model\GamePrivilegedTitle;
use app\model\GamePrivilegedTitleRecord;
use Exception;
use Illuminate\Database\Eloquent\Builder;
use support\Request;
use support\Response;

class GiftBagController
{

    /**
     * 获取配置
     *
     * @param Request $request
     * @return Response
     * @throws Exception
     */
    public function Init(Request $request): Response
    {

        requestValidator($request, [
            'game' => 'bail|required|exists:app\\model\\GameAuthorization,ulid,state,1,deleted_at,NULL',
            'area' => 'bail|required|exists:app\\model\\DistrictService,ulid,state,1,deleted_at,NULL',
            'role_id' => 'bail|required|string',
            'role_name' => 'bail|required|string',
            'boxLogin' => 'bail|required|string',
        ], [
            'game.required' => '游戏不能为空',
            'game.exists' => '游戏不存在',
            'area.required' => '区服不能为空',
            'area.exists' => '区服不存在',
            'role_id.required' => '请选择角色',
            'role_id.string' => '角色ID不正确',
            'role_name.required' => '请选择角色',
            'role_name.string' => '角色名称不正确',
            'boxLogin.required' => '请选择登录方式',
            'boxLogin.string' => '登录方式格式不正确',
        ]);

        $userInfo = $request->userInfo;

        $publicPlatformInfo = GetProductInfo::getInstance()->GetPublicPlatform();

        // 特权称号
        $privilegedTitleInfo = GamePrivilegedTitle::query()->where('game', $request->input('game'))->where('start_time', '<=', date('Y-m-d H:i:s'))->where(function (Builder $query) {
            $query->whereNull('end_time')->orWhere(function (Builder $query) {
                $query->whereNotNull('end_time')->where('end_time', '>', date('Y-m-d H:i:s'));
            });
        })->where('state', 1)->latest()->first();
        $privilegedTitleContent = [];
        if ($privilegedTitleInfo) {
            $receiveState = GamePrivilegedTitleRecord::query()->where('game', $request->input('game'))->where('privileged_title', $privilegedTitleInfo->ulid)
                ->where('user', $userInfo['ulid'])->where('role', $request->input('role_id'))->whereNotNull('use_area')
                ->where('use_area', $request->input('area'))->where('state', 1)->exists();

            if (!empty($privilegedTitleInfo->area)) {
                $areaList = json_decode($privilegedTitleInfo->area, true);
                if (in_array($request->input('area'), $areaList)) {
                    $privilegedTitleContent = [
                        'id' => $privilegedTitleInfo->number,
                        'title' => $privilegedTitleInfo->title,
                        'goods' => json_decode($privilegedTitleInfo->goods, true),
                        'state' => $receiveState,
                    ];
                }
            } else {
                $privilegedTitleContent = [
                    'id' => $privilegedTitleInfo->number,
                    'title' => $privilegedTitleInfo->title,
                    'goods' => json_decode($privilegedTitleInfo->goods, true),
                    'state' => $receiveState,
                ];
            }

        }
//        if (!empty($privilegedTitleContent) && !$privilegedTitleContent['state'] && $request->input('boxLogin') == 'true') {
        if (!empty($privilegedTitleContent) && $request->input('boxLogin') == 'true') {
            $recordInfo = GamePrivilegedTitleRecord::query()->updateOrCreate([
                'game' => $request->input('game'),
                'user' => $userInfo['ulid'],
                'role' => $request->input('role_id'),
                'privileged_title' => $privilegedTitleInfo->ulid,
                'use_area' => $request->input('area'),
            ], [
                'state' => 0,
                'remark' => 0,
            ]);

            // 通知游戏服务端下发特权称号
            AutoTaskRecord::query()->create([
                'label' => 'area-command',
                'params' => json_encode([
                    'cmd' => 'OVERLOAD',
                    'data' => [
                        'script' => 'PrivilegedTitle',
                        'ulid' => $recordInfo['ulid'],
                        'mch_id' => $privilegedTitleInfo->merchant,
                        'game_id' => $request->input('game'),
                        'area_id' => $request->input('area'),
                        'regionid' => $request->input('area'),
                        'chrid' => $request->input('role_id'),
                        'chrname' => $request->input('role_name'),
                        'number' => $privilegedTitleInfo->number, // 称号ID,
                        'goods' => json_decode($privilegedTitleInfo->goods, true),
                    ],
                    'callback_url' => $publicPlatformInfo['api_url'] . '/api/v1/server-callback/use-privileged-title',
                    'task_time' => date('Y-m-d H:i:s'),
                ]),
                'run_time' => time(),
                'state' => 0,
            ]);
        }


        // 每日礼包
        $everydayGiftInfo = GameGiftBag::query()->where('game', $request->input('game'))->where('start_time', '<=', date('Y-m-d H:i:s'))->where(function (Builder $query) {
            $query->whereNull('end_time')->orWhere(function (Builder $query) {
                $query->whereNotNull('end_time')->where('end_time', '>', date('Y-m-d H:i:s'));
            });
        })->where('type', 3)->where('state', 1)->latest()->first();
        $everydayGiftContent = [];
        if ($everydayGiftInfo) {
            $receiveState = GameGiftBagRecord::query()->where('game', $request->input('game'))->where('gift_bag', $everydayGiftInfo->ulid)
                ->where('user', $userInfo['ulid'])->where('role', $request->input('role_id'))->whereNotNull('use_area')->where('use_area', $request->input('area'))
                ->whereDate('use_time', date('Y-m-d'))->where('state', 2)->exists();

            if (!empty($everydayGiftInfo->area)) {
                $areaList = json_decode($everydayGiftInfo->area, true);
                if (in_array($request->input('area'), $areaList)) {
                    $everydayGiftContent = [
                        'goods' => json_decode($everydayGiftInfo->goods, true),
                        'state' => $receiveState,
                    ];
                }
            } else {
                $everydayGiftContent = [
                    'goods' => json_decode($everydayGiftInfo->goods, true),
                    'state' => $receiveState,
                ];
            }
        }


        // 兑换礼包
        $exchangeGiftCount = GameGiftBag::query()->where('game', $request->input('game'))->where('start_time', '<=', date('Y-m-d H:i:s'))->where(function (Builder $query) {
            $query->whereNull('end_time')->orWhere(function (Builder $query) {
                $query->whereNotNull('end_time')->where('end_time', '>', date('Y-m-d H:i:s'));
            });
        })->whereIn('type', [1, 2])->where('state', 1)->where(function (Builder $query) use ($request) {
            $query->whereNull('area')->orWhere(function (Builder $query) use ($request) {
                $query->whereNotNull('area')->whereJsonContains('area', (string)$request->input('area'));
            });
        })->count();
        $exchangeGiftContent = [
            'count' => $exchangeGiftCount,
        ];

        return jsonRe([
            // 特权称号
            'privileged_title' => [
                'state' => !empty($privilegedTitleContent),
                'content' => $privilegedTitleContent
            ],
            // 每日礼包
            'everyday_gift' => [
                'state' => !empty($everydayGiftContent),
                'content' => $everydayGiftContent
            ],
            // 兑换礼包
            'exchange_gift' => [
                'state' => true,
                'content' => $exchangeGiftContent
            ]
        ]);

    }


    /**
     * 兑换礼包
     *
     * @param Request $request
     * @return Response
     * @throws Exception
     */
    public function Exchange(Request $request): Response
    {

        requestValidator($request, [
            'game' => 'bail|required|exists:app\\model\\GameAuthorization,ulid,state,1,deleted_at,NULL',
            'area' => 'bail|required|exists:app\\model\\DistrictService,ulid,state,1,deleted_at,NULL',
            'role_id' => 'bail|required|string',
            'role_name' => 'bail|required|string',
            'type' => 'bail|required|in:1,2',  // 1每日礼包 2兑换礼包
            'code' => 'bail|required_if:type,2|string|max:50',
        ], [
            'game.required' => '游戏不能为空',
            'game.exists' => '游戏不存在',
            'area.required' => '区服不能为空',
            'area.exists' => '区服不存在',
            'role_id.required' => '请选择角色',
            'role_id.string' => '角色ID不正确',
            'role_name.required' => '请选择角色',
            'role_name.string' => '角色名称不正确',
            'type.required' => '请选择礼包类型',
            'type.in' => '礼包类型不正确',
            'code.required_if' => '请输入礼包码',
            'code.string' => '礼包码不正确',
            'code.max' => '礼包码不正确'
        ]);

        $userInfo = $request->userInfo;

        $giftRecord = null;
        if ($request->input('type') == 1) {
            $giftInfo = GameGiftBag::query()->where('game', $request->input('game'))->where('type', 3)->whereNotNull('goods')
                ->where('state', 1)->latest()->first();
        } else if ($request->input('type') == 2) {
            $giftRecord = GameGiftBagRecord::query()->where('code', $request->input('code'))->where('game', $request->input('game'))->latest()->first();
            if (!$giftRecord) {
                throw new Exception('礼包码不正确', 500);
            }
            if ($giftRecord->state === 0) {
                throw new Exception('礼包未领取', 500);
            }
            if ($giftRecord->state === 2) {
                throw new Exception('礼包已兑换', 500);
            }

            // 只能兑换普通礼包和会员礼包
            $giftInfo = GameGiftBag::query()->where('game', $request->input('game'))->whereIn('type', [1, 2])->where('ulid', $giftRecord->gift_bag)
                ->whereNotNull('goods')->where('state', 1)->first();
        } else {
            throw new Exception('礼包类型不正确', 500);
        }

        if (!$giftInfo) {
            throw new Exception('礼包不存在', 500);
        }
        if (strtotime($giftInfo->start_time) > time()) {
            throw new Exception('礼包未开始兑换', 500);
        }
        if (!empty($giftInfo->end_time) && strtotime($giftInfo->end_time) < time()) {
            throw new Exception('礼包已结束兑换', 500);
        }
        if (!empty($giftInfo->area)) {
            $areaList = json_decode($giftInfo->area, true);
            if (!in_array($request->input('area'), $areaList)) {
                throw new Exception('当前区服不可兑换该礼包', 500);
            }
        }

        // 今日礼包相关验证
        if ($request->input('type') == 1) {
            if (!empty($giftInfo->count)) {
                $todayExchangeCount = GameGiftBagRecord::query()->where('game', $request->input('game'))->where('gift_bag', $giftInfo->ulid)
                    ->whereDate('use_time', date('Y-m-d'))->where('state', 2)->count();
                if ($giftInfo->count <= $todayExchangeCount) {
                    throw new Exception('今日兑换量已达上限', 500);
                }
            }

            $myTodayExchangeState = GameGiftBagRecord::query()->where('game', $request->input('game'))->where('gift_bag', $giftInfo->ulid)
                ->where('user', $userInfo['ulid'])->where('role', $request->input('role_id'))->whereDate('use_time', date('Y-m-d'))
                ->where('state', 2)->exists();
            if ($myTodayExchangeState) {
                throw new Exception('今日已兑换', 500);
            }
        }

        try {
            if ($request->input('type') == 1) {
                $giftRecord = GameGiftBagRecord::query()->create([
                    'user' => $userInfo['ulid'],
                    'game' => $request->input('game'),
                    'gift_bag' => $giftInfo->ulid,
                    'role' => $request->input('role_id'),
                    'code' => $giftInfo->ulid,
                    'use_area' => $request->input('area'),
                    'use_time' => date('Y-m-d H:i:s'),
                    'state' => 2,
                    'remark' => '兑换成功',
                ]);
            } else {
                $giftRecord->update([
                    'use_area' => $request->input('area'),
                    'use_time' => date('Y-m-d H:i:s'),
                    'state' => 2,
                    'remark' => '兑换成功',
                ]);
            }
        } catch (Exception) {
            throw new Exception('兑换失败', 500);
        }

        $publicPlatformInfo = GetProductInfo::getInstance()->GetPublicPlatform();

        // 通知游戏服务端下发礼包物品
        AutoTaskRecord::query()->create([
            'label' => 'area-command',
            'params' => json_encode([
                'cmd' => 'OVERLOAD',
                'data' => [
                    'script' => 'GiftPack',
                    'ulid' => $giftRecord['ulid'],
                    'mch_id' => $giftInfo->merchant,
                    'game_id' => $request->input('game'),
                    'area_id' => $request->input('area'),
                    'regionid' => $request->input('area'),
                    'data' => [
                        'chrid' => $request->input('role_id'),
                        'chrname' => $request->input('role_name'),
                        'type' => $giftInfo->type,
                        'goods' => json_decode($giftInfo->goods, true),
                    ],
                ],
                'callback_url' => $publicPlatformInfo['api_url'] . '/api/v1/server-callback/exchange-game-gift',
                'task_time' => date('Y-m-d H:i:s'),
            ]),
            'run_time' => time(),
            'state' => 0,
        ]);

        return jsonRe();

    }


    /**
     * 兑换礼包列表
     *
     * @param Request $request
     * @return Response
     * @throws Exception
     */
    public function ExchangeGiftList(Request $request): Response
    {

        requestValidator($request, [
            'game' => 'bail|required|exists:app\\model\\GameAuthorization,ulid,state,1,deleted_at,NULL',
            'area' => 'bail|required|exists:app\\model\\DistrictService,ulid,state,1,deleted_at,NULL',
            'role_id' => 'bail|required|string',
            'role_name' => 'bail|required|string',
        ], [
            'game.required' => '游戏不能为空',
            'game.exists' => '游戏不存在',
            'area.required' => '区服不能为空',
            'area.exists' => '区服不存在',
            'role_id.required' => '请选择角色',
            'role_id.string' => '角色ID不正确',
            'role_name.required' => '请选择角色',
            'role_name.string' => '角色名称不正确',
        ]);

        $userInfo = $request->userInfo;
        $noPage = max(1, $request->input('no_page') ?? 1);
        $pageSize = max(1, $request->input('page_size') ?? 10);

        $listSql = GameGiftBag::query()->where('game', $request->input('game'))->where('start_time', '<=', date('Y-m-d H:i:s'))->where(function (Builder $query) {
            $query->whereNull('end_time')->orWhere(function (Builder $query) {
                $query->whereNotNull('end_time')->where('end_time', '>', date('Y-m-d H:i:s'));
            });
        })->whereIn('type', [1, 2])->where('state', 1)->where(function (Builder $query) use ($request) {
            $query->whereNull('area')->orWhere(function (Builder $query) use ($request) {
                $query->whereNotNull('area')->whereJsonContains('area', (string)$request->input('area'));
            });
        })->oldest('start_time');

        $list = $listSql->skip(($noPage - 1) * $pageSize)->take($pageSize)->get()->map(function ($row) use ($request, $userInfo) {
            $exchangeState = GameGiftBagRecord::query()->where('game', $request->input('game'))->where('gift_bag', $row['ulid'])
                ->where('user', $userInfo['ulid'])->whereNotNull('use_area')->where('use_area', $request->input('area'))
                ->where('state', 2)->exists();

            return [
                'ulid' => $row['ulid'],
                'type' => $row['type'],
                'goods' => json_decode($row['goods'], true),
                'state' => $exchangeState,
            ];
        })->toArray();

        return jsonRe([
            'list' => $list,
            'pagination' => [
                'no_page' => $noPage,
                'page_size' => $pageSize,
                'total_page' => ceil((clone $listSql)->count() / $pageSize),
                'total_count' => (clone $listSql)->count(),
            ]
        ]);

    }

}